var $ = require;

var path = $('path');
require.paths.unshift(path.join(__dirname, '../..', 'services'));  //add services to require.paths
var registerService = $('registerService');

var vows = $('vows'),
    assert = $('assert'),
    _ = $('underscore');

var addedUser = {
    "oauth_access_token": "2f9f60a853cf7107b2aba061f3538741",
    "oauth_access_token_secret": "f0afa8fd6d2ccab5bc3c8e2cb5014a07",
    "user_id": 1
};

vows.describe('test RegisterService').addBatch({

    //one context, may contains many topic or nested context
    'registerService.getAll': {
        topic: function(){
            registerService.getAll(this.callback);
        },

        'no error': function(err, users){
                assert.isNull( err, (err) ? err.message : null  );
        },

        'results is not empty': function(err, users){
             assert.isArray(users);
             assert.isTrue(users.length > 0);
        }
    },
}).addBatch({
    'add one user':{
        topic: function(){
            registerService.add(addedUser, this.callback);
        },

        'user added': function(err, user){
            this.savedUser = user;
            assert.isNull(err, err ? err.message : 'err undefined');
            assert.isTrue(_.isEqual(addedUser, user));
        },

        'fetch user': {
            topic: function(){
                var me = this;
                registerService.get(this.savedUser.user_id, this.callback);
            },

            'user fetched': function(err, fetchedUser){
                console.log('user fetched');
                var isEqual = true;
                assert.isTrue(_.isEqual(this.savedUser, fetchedUser));
            }
        }
    }
}).addBatch({
    'remove added user': {
        topic: function(){
            registerService.delete(addedUser, this.callback)
        },

        'after remove user': function(err, affectedRow){
            assert.equal(1, affectedRow);
        }
    }
}).addBatch({
    //nested topics execute parrale, therefore we add two batches to test upsert
    'upsert a new user':{
        topic: function(){
            var me = this;
            registerService.getAll(function(err, results){
                me.userCountBeforeUpsert = results.length;
                registerService.upsert(addedUser, me.callback);
            });
        },

        'a new user added by upsert': function(err, newuser){
            assert.isNull(err, err && err.message ? err.message : 'upsert fail: reason unknown');
            assert.isNotNull(newuser);
            assert.isTrue(newuser.user_id == addedUser.user_id);
            assert.isTrue(_.isEqual(newuser, addedUser));
        },

        'user count inc 1 after upsert': function(err, newuser){
            var countBefore = this.userCountBeforeUpsert;
            registerService.getAll(function(err, results){
                assert.isTrue(countBefore + 1 == results.length);
            });
        },

        //teardown also works well
        teardown: function(){
            registerService.delete(addedUser, function(err, affectedRow){
                //console.log('upsert teardown: remove new added user');
                assert.equal(1, affectedRow);
            });
        }
    }
}).addBatch({
    'upsert an existing user': {
        topic: function(){
            var me = this;
            var existingUser= {
                "oauth_access_token": "2f9f60a853cf7107b2aba061f3538741",
                "oauth_access_token_secret": "f0afa8fd6d2ccab5bc3c8e2cb5014a07",
                "user_id": 2212375377
            };
            me.existingUser = existingUser;
            registerService.getAll(function(err, results){
                me.userCountBeforeUpsert = results.length;
                console.log(me.userCountBeforeUpsert + '====before upsert');
                registerService.upsert(existingUser, me.callback);
            });
        },

        'a new user added by upsert': function(err, newuser){
            assert.isNull(err, err && err.message ? err.message : 'upsert fail: reason unknown');
            assert.isNotNull(newuser);
            assert.isTrue(_.isEqual(newuser, this.existingUser));
        },

        'user count is not changed after upsert': function(err, newuser){
            var countBefore = this.userCountBeforeUpsert;
            registerService.getAll(function(err, results){
                assert.isTrue(countBefore == results.length);
            });
        }
    }
})
.run();
